import logging
log=logging.getLogger(__name__)
class Rule(object):
    def __init__(self,**kwargs):
        action=self.action=kwargs.get('action')
        controller=self.controller=kwargs.get('controller')
        path=self.path=kwargs.get('path')
        if (action or controller) and path :
            raise ValueError('Rules can not handle noth actions and controller format and url format')
        self.exceptActions=kwargs.get('exceptActions',[])
        self.exceptControllers=kwargs.get('excpetControllers',[])
        self.exceptPaths=kwargs.get('exceptPath',[])
        self.opt=kwargs.get('opt',{})
        self._kwargs=kwargs

    def check(self,path,controller,action):
        if self.path and not (path==self.path) : return False
        log.info('pass path')
        if self.action and not (action==self.action) : return False
        log.info('pass action')
        if self.controller and not(controller==self.controller) : return False
        log.info('pass controller')
        if path in self.exceptPaths : return False
        if action in self.exceptActions : return False
        if controller in self.exceptControllers : return False
        return True

class BaseRulesMiddleware(object):

    def __init__(self,app,rules):
        self.app=app
        self.rules=rules

    def __call__(self,environ,start_response):
        session=environ['beaker.session']
        path=environ['PATH_INFO']
        controller=environ['wsgiorg.routing_args'][1].get('controller','')
        action = environ['wsgiorg.routing_args'][1].get('action','')
        for rule in self.rules :
            if rule.check(path,controller,action):
                return self._call(environ,start_response,rule.opt)
        return self.app(environ,start_response)

    def set_call(self,func):
        if not hasattr(func,'__call__'): raise TypeError('func must be callable')
        self._call=func
